﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace WizzardTheGame
{
    abstract class Character: IDrawable
    {
        protected const float GRAVITY = 0.2f;
        private const int MAX_GRAVITY = -3;
        private const Int32 DEFAULT_HP = 100;
        private const Int32 DEFAULT_EXP = 100;
        private const Int32 DEFAULT_ATTACK = 10;
        private const float DEFAULT_SPEED = 0.5f;
        private Object3D charModel;
        private int maxHP;
        private int currentHP;
        private int attackPower;
        private int defense;
        private float speed;
        private Inventory inventory;
        private int experience;
        private int gold;
        private Vector3 velocity;
        private Vector3 position;
        private bool isAlive;

        #region Properties


        public Object3D CharModel
        {
            get { return charModel; }
            set { charModel = value; }
        }

        public int MaxHP
        {
            get { return maxHP; }
            set { maxHP = value; }
        }

        public Inventory Inventory
        {
            get { return inventory; }
            set { inventory = value; }
        }

        public int CurrentHP
        {
            get { return currentHP; }
            set { currentHP = value; }
        }

        public float Speed
        {
            get { return speed; }
            set { speed = value; }
        }

        public int AttackPower
        {
            get { return attackPower; }
            set { attackPower = value; }
        }

        public int Defense
        {
            get { return defense; }
            set { defense = value; }
        }

        public virtual int Experience
        {
            get { return experience; }
            set { experience = value; }
        }

        public int Gold
        {
            get { return gold; }
            set { gold = value; }
        }

        public Vector3 Velocity
        {
            get { return velocity; }
            set
            {
                velocity = value;
                CharModel.Velocity = value;
            }
        }

        public virtual Vector3 Position
        {
            get { return position; }
            set 
            { 
                position = value;
                CharModel.Position = value;
            }
        }

        public bool IsAlive
        {
            get { return isAlive; }
            set { isAlive = value; }
        }
        #endregion

        protected Character(string path):this()
        {
            CharModel = new Object3D(path);
        }

        protected Character()
        {
            if(CharModel == null) CharModel = new Object3D();
            MaxHP = DEFAULT_HP;
            CurrentHP = DEFAULT_HP;
            Experience = DEFAULT_EXP;
            AttackPower = DEFAULT_ATTACK;
            Speed = DEFAULT_SPEED;
            Gold = 0;
            Velocity = Vector3.Zero;
            Position = Vector3.Zero;
            IsAlive = true;
            Inventory = new Inventory();
        }

        public virtual void Update()
        {
            ApplyGravity();
            Position += Velocity;
        }
        protected abstract void Attack();


        protected virtual void ApplyGravity()
        {
            int i = 0;
            bool collision = false;
            List<GameEnvironment> gameEnvs = GameWorld.getInstance().GameEnvironment;
            while (!collision && i < gameEnvs.Count)
            {
                collision = gameEnvs[i].EnvModel.TestCollision(CharModel);
                i++;
            }
            Vector3 gravity = Velocity;
            if (!collision)
            {
                if (!(Velocity.Y < MAX_GRAVITY))
                {
                    //Apply gravity
                    gravity.Y -= GRAVITY;
                    Velocity = gravity;
                }
            }
            else
            {
                gravity.Y = 0f;
            }
            Velocity = gravity;
        }

        #region IDrawable Members

        public virtual void Draw()
        {
            CharModel.Draw();
        }

        #endregion
    }
}
